<template>
  <el-row :gutter="10" class="sencond-line">
    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="laser.name" :time="laser.createTime">
          <template v-slot:sensor>
            <h3>
              <svg-icon icon="laser"></svg-icon>{{ facValue.laserValue }}米
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>
    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="metal.name" :time="metal.createTime">
          <template v-slot:sensor>
            <h3>
              <el-icon><Magnet /></el-icon
              >{{ metal.metalDetection === 0 ? '无' : '有' }}
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>
    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="shear.name" :time="shear.createTime">
          <template v-slot:sensor>
            <h3>
              <svg-icon icon="vibrate"></svg-icon>{{ facValue.shearValue }}g
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>

    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="longitude.name" :time="longitude.createTime">
          <template v-slot:sensor>
            <h3>
              <svg-icon icon="vibrate"></svg-icon>{{ facValue.longitudeValue }}g
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>
    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="noise.name" :time="noise.createTime">
          <template v-slot:sensor>
            <h3>
              <svg-icon icon="noise"></svg-icon>{{ facValue.noiseValue }}db
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>
    <el-col :span="4">
      <el-card class="sensor">
        <sensor :title="infrared.name" :time="infrared.createTime">
          <template v-slot:sensor>
            <h3>
              <svg-icon icon="human-body"></svg-icon
              >{{ infrared.humanBodyInfrared === 0 ? '无人' : '有人' }}
            </h3>
          </template>
        </sensor>
      </el-card>
    </el-col>
  </el-row>
  <el-row :gutter="20" class="first-line">
    <el-col :span="12">
      <el-card class="map">
        <div id="container-map"></div>
        <div class="map-title">设备运行分布</div>
      </el-card>
    </el-col>

    <el-col :span="12">
      <el-card class="fac-info">
        <div class="sys-status">
          <div>
            <el-icon><List /></el-icon><span class="title-style">系统状态</span>
          </div>
          <Time v-on:getSystemInfoAndSensorInfo="getSystemInfoAndSensorInfo" />
        </div>
        <el-descriptions direction="horizontal" :column="2" border>
          <template #title>
            <div class="sensor-backcolor">传感网</div>
          </template>
          <el-descriptions-item label="无线类型">{{
            systemObject.wireLineType
          }}</el-descriptions-item>
          <el-descriptions-item label="PANID">{{
            systemObject.panid
          }}</el-descriptions-item>
          <el-descriptions-item label="信道编号">{{
            systemObject.signalNo
          }}</el-descriptions-item>
          <el-descriptions-item label="入网节点数">{{
            systemObject.registerNode
          }}</el-descriptions-item>
          <el-descriptions-item label="在线节点数">{{
            systemObject.onlineNode
          }}</el-descriptions-item>
          <el-descriptions-item label="离线节点数">{{
            offlineNode
          }}</el-descriptions-item>
        </el-descriptions>
        <el-descriptions direction="horizontal" :column="2" border>
          <template #title>
            <div class="sensor-backcolor">以太网</div>
          </template>
          <el-descriptions-item label="ip获取类型">{{
            systemObject.ipType
          }}</el-descriptions-item>
          <el-descriptions-item label="ip地址">{{
            systemObject.ipAddress
          }}</el-descriptions-item>
        </el-descriptions>
        <el-descriptions direction="horizontal" :column="2" border>
          <template #title>
            <div class="sensor-backcolor">Wi-Fi</div>
          </template>
          <el-descriptions-item label="状态">关闭</el-descriptions-item>
          <el-descriptions-item label="接入点"></el-descriptions-item>
          <el-descriptions-item label="ip地址"></el-descriptions-item>
        </el-descriptions>
        <el-descriptions direction="horizontal" :column="2" border>
          <template #title>
            <div class="sensor-backcolor">3G/4G</div>
          </template>
          <el-descriptions-item label="状态">已开启</el-descriptions-item>
          <el-descriptions-item label="ip地址"></el-descriptions-item>
        </el-descriptions>
      </el-card>
    </el-col>
  </el-row>

  <InfoWindow
    :currentSesnorInfo="currentSesnorInfo"
    :buttonRef="buttonRef"
    :actualLocation="actualLocation"
  />
  <div id="infoWindow">
    <div style="font-weight: 600; margin-bottom: 6px">
      <span>{{ currentSesnorInfo.type }}</span>
    </div>
    <div class="item-style">
      <span>上行LQI：</span>{{ currentSesnorInfo.upLqi }}
    </div>
    <div class="item-style">
      <span>下行LQI：</span>{{ currentSesnorInfo.downLqi }}
    </div>
    <div class="item-style"><span>mac：</span>{{ currentSesnorInfo.mac }}</div>
    <div class="item-style">
      <span>上报间隔：</span>{{ currentSesnorInfo.reportInterval }}
    </div>
    <div class="item-style"><span>值：</span>{{ currentSesnorInfo.value }}</div>
    <div class="item-style">
      <span>创建时间：</span>{{ currentSesnorInfo.nodeCreateTime }}
    </div>
    <div class="item-style">
      <span>状态：</span>{{ currentSesnorInfo.status === 1 ? '正常' : '异常' }}
    </div>
    <div class="item-style"><span>地址：</span>{{ actualLocation }}</div>
  </div>
</template>

<script setup>
import gsap from 'gsap'
import { reactive, shallowRef } from '@vue/reactivity'
import AMapLoader from '@amap/amap-jsapi-loader'
import {
  ref,
  computed,
  onUnmounted,
  onMounted,
  watch,
  setBlockTracking
} from 'vue'
import { useStore } from 'vuex'
import { Histogram, Monitor, List } from '@element-plus/icons-vue'
import cloneDeep from 'lodash/cloneDeep'
import bus from '../../mitt/index'
import {
  getSystemInfoAndSensorInfo as getSystemAndSensor,
  getNewStatusData
} from '@/api/facility.js'
import { ElMessage } from 'element-plus'
import InfoWindow from './components/InfoWindow.vue'
import Time from './components/time.vue'

// import { onBeforeRouteLeave } from 'vue-router'

/* 引入安全密钥 onBeforeRouteLeave官方不推荐这个用法*/
window._AMapSecurityConfig = {
  securityJsCode: '9c6705088cb3f2de2ce3ce720a10e33b'
}

const infoWindow = ref(null)

const store = useStore()

const buttonRef = ref()

const sensorInfoList = ref([])

const currentSesnorInfo = ref({
  upLqi: '',
  downLqi: '',
  mac: '',
  reportInterval: '',
  value: '',
  status: '',
  createTime: '',
  type: '',
  longitudeAndLatitude: '',
  position: ''
})

const facValue = reactive({
  noiseValue: 0,
  laserValue: 0,
  longitudeValue: 0,
  shearValue: 0
})
const systemObject = ref({})

const laser = ref({})

const shear = ref({})

const longitude = ref({})

const noise = ref({ environmentalNoise: 0 })

const metal = ref({})
const infrared = ref({})

const offlineNode = computed(() => {
  return systemObject.value.registerNode - systemObject.value.onlineNode
})

const map = shallowRef(null)

const markers = ref([])

const actualLocation = ref('')

const backgroundColor = ref('')
let borderColor = ref('')
onMounted(() => {
  ElNotification({
    title: '警告',
    message: '有人入侵',
    type: 'error',
    duration: 50000
  })
  // 报警监测
  var socket
  if (window.WebSocket) {
    socket = new WebSocket('ws://127.0.0.1:8080/fmms/nodeController/alarmInfo')
    socket.onmessage = function (ev) {
      ElMessage.success(ev)
    }

    socket.onclose = function () {
      ElMessage({
        type: 'error',
        duration: 1500,
        message: '关闭连接'
      })
    }

    socket.onopen = function () {
      ElMessage({
        type: 'success',
        duration: 1500,
        message: '连接成功'
      })
    }
  } else {
    alert('浏览器不支持WebSocket')
  }

  function send(message) {
    if (!window.socket) {
      return
    }
    if (socket.readyState === WebSocket.OPEN) {
      socket.send(message)
    }
  }
})
watch(
  () => store.getters.themeStatus,
  () => {
    backgroundColor.value = store.getters.themeStatus ? '#141414' : '#fff'
    borderColor.value = store.getters.themeStatus ? '#141414' : '#fff'
  },
  { deep: true, immediate: true }
)

/* 地图初始化函数 initMap */
const initMap = () => {
  AMapLoader.load({
    key: '6f83a8468ec3392314cb52572e2cefb1', // 申请好的Web端开发者Key，首次调用 load 时必填
    version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
    plugins: ['AMap.Geocoder', 'AMap.HawkEye'] // 需要使用的的插件列表，如比例尺'AMap.Scale'等
  })
    .then((AMap) => {
      map.value = new AMap.Map('container-map', {
        //设置地图容器id
        viewMode: '3D', //是否为3D地图模式
        zoom: 13, //初始化地图级别
        center: [116.397428, 39.90923], //初始化地图中心点位置
        resizeEnable: true
      })

      const overView = new AMap.HawkEye({
        visible: true
      })
      // 在图面添加比例尺控件，展示地图在当前层级和纬度下的比例尺
      map.value.addControl(overView)

      map.value.clearMap() // 清除地图覆盖物

      const infoWindow = new AMap.InfoWindow({
        //创建信息窗体
        isCustom: false, //使用自定义窗体
        // content 可以是 dom 对象，也可以是 html 识别的字符串
        content: document.getElementById('infoWindow'), //信息窗体的内容可以是任意html片段
        offset: new AMap.Pixel(0, -66)
      })

      // 逆向地理编码服务
      const getLngService = () => {
        const geocoder = new AMap.Geocoder({
          // city 指定进行编码查询的城市，支持传入城市名、adcode 和 citycode
          city: '全国'
        })
        return geocoder
      }

      const onMarkerClick = (e) => {
        // 获取点击点的经纬度
        const lnglat = e.target.getPosition()
        // 当点击标记点获取逆向地理编码
        const geocoder = getLngService()
        geocoder.getAddress(lnglat, (status, result) => {
          if (status === 'complete' && result.info === 'OK') {
            // result为对应的地理位置详细信息
            actualLocation.value = result.regeocode.formattedAddress
            // console.log(result.regeocode.formattedAddress)
          }
        })
        // 当前点击的经纬度
        const currentlnglat = [lnglat.lng, lnglat.lat]
        // 根据经纬度获取当前节点信息
        const res = cloneDeep(sensorInfoList.value).filter(
          // 调用join方法将数组转为字符串
          (item) => item.longitudeAndLatitude === currentlnglat.join()
        )
        currentSesnorInfo.value = res[0]
        // bus.emit('getCurrentNodeInfo', res)
        // console.log(currentSesorInfo.value)
        infoWindow.open(map.value, e.target.getPosition()) //打开信息窗体
        //e.target就是被点击的Marker
      }

      // 此处使用仓库解决标记点丢失的问题
      const markersList = store.getters.mapInfoList
      // 添加一些分布不均的点到地图上,地图上添加三个点标记，作为参照
      markersList.forEach(function (marker) {
        // 创建多个 Marker 实例
        const mapMarker = new AMap.Marker({
          map: map.value,
          icon: marker.icon,
          position: [marker.position[0], marker.position[1]],
          offset: new AMap.Pixel(0, 0)
        })
        mapMarker.on('mouseover', onMarkerClick)
        mapMarker.on('click', onMarkerClick)
      })

      // 将创建的点标记添加到已有的地图实例：
      // map.add(marker) //单个点需要这个方法多个不需要

      // 设置初始化自动自适应
      // 第一个参数为空，表明用图上所有覆盖物 setFitview
      // 第二个参数为false, 非立即执行
      // 第三个参数设置上左下右的空白
      map.value.setFitView(null, true, [150, 135, 100, 50])
      // 这个是地图初始化后发生的点击事件，在这里只需要实现点击标记点获取逆向地理即可，故无用
      map.value.on('click', getLngService())
    })
    .catch((e) => {
      console.log(e)
    })
}

const getSystemInfoAndSensorInfo = async () => {
  try {
    const res = await getSystemAndSensor()
    // console.log(res)
    systemObject.value = res.data[1]
    shear.value = res.data[0]
    metal.value = res.data[2]
    longitude.value = res.data[3]
    laser.value = res.data[4]
    infrared.value = res.data[5]
    noise.value = res.data[6]
  } catch (error) {
    ElMessage.error(error)
  }
}

// 当侦听多个来源时，回调函数接受两个数组，分别对应来源数组中的新值和旧值：
watch(
  [noise, laser, shear, longitude],
  ([noi, las, she, lon], [prenoi, prelas, preshe, prelon]) => {
    gsap.to(facValue, {
      duration: 1,
      noiseValue: Number(noi.environmentalNoise) || 0
    })
    gsap.to(facValue, {
      duration: 1,
      laserValue: Number(las.laserRanging) || 0
    })
    gsap.to(facValue, {
      duration: 1,
      shearValue: Number(she.shearWave) || 0
    })
    gsap.to(facValue, {
      duration: 1,
      longitudeValue: Number(lon.longitudinalWave) || 0
    })
  },
  { immediate: true, deep: true }
)

const initGetNewStatusData = async () => {
  try {
    const res = await getNewStatusData()

    const handlerRes = res.data.map((item) => {
      const {
        type,
        mac,
        value,
        address,
        upLqi,
        downLqi,
        reportInterval,
        status,
        nodeCreateTime
      } = item
      return {
        type,
        mac,
        value,
        longitudeAndLatitude: address,
        position: address.split(',').map((item) => parseFloat(item)),
        upLqi,
        downLqi,
        reportInterval,
        status,
        nodeCreateTime
      }
    })
    // console.log(handlerRes)
    await store.commit('app/saveMapInfoList', handlerRes)
    markers.value = store.getters.mapInfoList
    sensorInfoList.value = store.getters.mapInfoList
  } catch (error) {
    ElMessage.error(error)
  }
}
initGetNewStatusData()
getSystemInfoAndSensorInfo()

// const resetFacilityStatus = () => {}

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  // 销毁地图，并清空地图容器
  map.value && map.value.destroy()
})
</script>

<style lang="scss" scoped>
@media screen and (max-width: 1000px) {
  .first-line {
    flex-direction: column;
    & .el-col:nth-child(2) {
      margin-top: 15px;
    }
  }
  :deep(.el-col-12) {
    max-width: 100%;
  }
  .sencond-line {
    flex-direction: column;
    :deep(.el-col-4) {
      max-width: 100%;
      flex: 1;
    }
  }
}

/* .sencond-line {
  display: flex;
  justify-content: space-between;
}
 */
.map {
  position: relative;
  :deep(.el-card__body) {
    padding: 0px;
  }
  .map-title {
    width: 100%;
    position: absolute;
    top: 10px;
    text-align: center;
    z-index: 10;
    font-size: 20px;
    font-weight: 600;
    color: blue;
    letter-spacing: 2px;
  }
}
.fac-info {
  min-width: 240px;
  width: 100%;
  height: 100%;
  .sys-status {
    display: flex;
    align-items: middle;
    justify-content: space-between;
    .title-style {
      font-size: 20px;
      font-weight: 600;
    }

    margin-bottom: 10px;
  }
  :deep(.el-descriptions__header) {
    margin-bottom: 5px;
  }
  :deep(.el-descriptions__title) {
    flex: 1;
    margin-top: 10px;
  }
  .sensor-backcolor {
    color: white;
    height: 30px;
    line-height: 30px;
    vertical-align: middle;
    text-align: center;
    background-color: #bfa;
    width: 100%;
  }
}
.sensor {
  // margin-top: 20px;
  margin-bottom: 20px;
  height: 180px;
  padding: 0px;
  :deep(.el-card__body) {
    padding: 0px;
  }
}
#container-map {
  min-width: 400px;
  height: 560px;
  :deep(.amap-info-contentContainer) {
    width: 250px;
  }
  :deep(.item-style) {
    font-size: 14px;
  }
  :deep(.amap-info-outer, .amap-menu-outer) {
    border-radius: 12px;
  }

  :deep(.amap-info-content) {
    background-color: v-bind(backgroundColor);
  }
  :deep(.bottom-center .amap-info-sharp, .bottom-center
      .amap-info-sharp:after) {
    border-color: v-bind(borderColor);
    margin-left: -8px;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
  }
}
</style>
